using AutoMapper;
using MD5Hash;
using MediatR;
using S.O.Api.Write.Application.Command.User;
using S.O.Domain.RBAC;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;
using System.Transactions;

namespace S.O.Api.Write.Application.Handler.User
{
    /// <summary>
    /// 创建用户处理器
    /// 负责处理用户创建的业务逻辑，包括用户信息创建和角色分配
    /// </summary>
    public class CreateUserHandler : IRequestHandler<CreateUserCommand, APIResult<int>>
    {
        /// <summary>
        /// 用户仓储接口，用于用户数据的CRUD操作
        /// </summary>
        private readonly IBaseRepository<UserModel> userRepository;
        
        /// <summary>
        /// 日志记录器，用于记录操作日志和错误信息
        /// </summary>
        private readonly ILogger<CreateUserHandler> logger;
        
        /// <summary>
        /// 对象映射器，用于Command对象到Model对象的转换
        /// </summary>
        private readonly IMapper mapper;
        
        /// <summary>
        /// 用户角色关联仓储接口，用于管理用户和角色的关联关系
        /// </summary>
        private readonly IBaseRepository<UserRoleModel> userRoleRepository;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需的服务
        /// </summary>
        /// <param name="userRepository">用户仓储服务</param>
        /// <param name="logger">日志记录服务</param>
        /// <param name="mapper">对象映射服务</param>
        /// <param name="userRoleRepository">用户角色关联仓储服务</param>
        public CreateUserHandler(IBaseRepository<UserModel> userRepository, ILogger<CreateUserHandler> logger, IMapper mapper, IBaseRepository<UserRoleModel> userRoleRepository)
        {
            this.userRepository = userRepository;
            this.logger = logger;
            this.mapper = mapper;
            this.userRoleRepository = userRoleRepository;
        }
        
        /// <summary>
        /// 处理创建用户命令
        /// 执行用户创建操作，包括密码加密、用户信息保存和角色分配，使用事务确保数据一致性
        /// </summary>
        /// <param name="request">创建用户命令对象，包含要创建的用户信息</param>
        /// <param name="cancellationToken">取消令牌，用于取消异步操作</param>
        /// <returns>返回包含操作结果的APIResult对象</returns>
        public Task<APIResult<int>> Handle(CreateUserCommand request, CancellationToken cancellationToken)
        {
            // 初始化返回结果对象
            APIResult<int> res = new APIResult<int>();
            
            // 使用AutoMapper将创建用户命令对象映射为用户实体对象
            var user = mapper.Map<UserModel>(request);
            
            // 对用户密码进行MD5加密处理
            user.Password = user.Password.GetMD5();
            
            // 使用事务确保用户创建和角色分配的原子性操作
            using (TransactionScope tran = new TransactionScope())
            {
                try
                {
                    // 创建用户记录
                    var r1 = userRepository.Create(user);

                    // 为新创建的用户分配角色
                    foreach (var item in request.RoleId)
                    {
                        var userrole = new UserRoleModel()
                        {
                            UserId = user.Id,
                            RoleId = item,
                        };
                        var r2 = userRoleRepository.Create(userrole);
                    }
                    
                    // 提交事务
                    tran.Complete();
                    
                    // 设置成功响应
                    res.Code = APIEnums.Success;
                    res.Data = r1;
                    res.Msg = "添加成功";
                    logger.LogInformation($"创建用户{request.UserName}成功");
                }
                catch (Exception ex)
                {
                    // 事务会自动回滚，设置错误响应
                    res.Code= APIEnums.Error;
                    res.Msg = "创建用户失败";
                    res.Data = 0;
                    logger.LogError($"创建用户{request.UserName}失败：{ex.Message}");
                    throw;
                }
            }
            return Task.FromResult(res);
        }
    }
}
